package com.atguigu.gmall.order.service.impl;
import java.util.Date;
import java.math.BigDecimal;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.constant.GmallConstant;
import com.atguigu.gmall.common.execption.GmallException;
import com.atguigu.gmall.common.feign.cart.CartFeignClient;
import com.atguigu.gmall.common.feign.product.SkuFeignClient;
import com.atguigu.gmall.common.feign.util.AuthUserInfoUtils;
import com.atguigu.gmall.common.feign.ware.WareFeignClient;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.enums.OrderStatus;
import com.atguigu.gmall.enums.ProcessStatus;
import com.atguigu.gmall.order.dto.DetailDto;
import com.atguigu.gmall.order.dto.OrderSubmitDto;
import com.atguigu.gmall.order.entity.*;
import com.atguigu.gmall.order.mapper.OrderStatusLogMapper;
import com.atguigu.gmall.order.mapper.PaymentInfoMapper;
import com.atguigu.gmall.order.service.OrderDetailService;
import com.atguigu.gmall.order.vo.WareSkuMapVo;
import com.atguigu.gmall.product.entity.SkuInfo;
import com.atguigu.gmall.rabbit.constant.RabbitConstant;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author xueyoupeng
* @description 针对表【order_info(订单表 订单表)】的数据库操作Service实现
* @createDate 2023-07-27 14:18:16
*/
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService{

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private OrderInfoMapper orderInfoMapper ;

    @Autowired
    private SkuFeignClient skuFeignClient ;

    @Autowired
    private OrderDetailService orderDetailService ;

    @Autowired
    private OrderStatusLogMapper orderStatusLogMapper ;

    @Autowired
    private CartFeignClient cartFeignClient ;

    @Autowired
    private WareFeignClient wareFeignClient ;

    @Autowired
    private RabbitTemplate rabbitTemplate ;

    @Autowired
    private PaymentInfoMapper paymentInfoMapper ;

    private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10);

    @Override
    public String submitOrder(String tradeNo, OrderSubmitDto orderSubmitDto) {

        // 判断外部交易号在Redis中所是否存在，如果不存在删除，然后执行后续逻辑(lua脚本实现)
        String script = "if redis.call('exists' , KEYS[1])\n" +
                "then\n" +
                "    return redis.call('del' , KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end" ;
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList(GmallConstant.REDIS_ORDER_CONFIRM + tradeNo));
        if (result == 0){
            throw new GmallException(ResultCodeEnum.ORDER_REPT);
        }

        // 校验价格
        List<DetailDto> detailDtoList = orderSubmitDto.getOrderDetailList();
        List<DetailDto> collect = detailDtoList.stream().filter(detailDto -> {
            Long skuId = detailDto.getSkuId();
            Result<SkuInfo> skuInfoResult = skuFeignClient.findSkuInfoBySkuId(skuId);
            SkuInfo skuInfo = skuInfoResult.getData();
            //把价格不相等的数据存在流里面
            return skuInfo.getPrice().doubleValue() != detailDto.getOrderPrice().doubleValue();
        }).collect(Collectors.toList());
        //如果流里面有数据 说明存在商品数据库的价格 和 页面不一致的 情况
        if (collect.size() > 0){
            throw new GmallException(ResultCodeEnum.SKU_PRICE_ERROR) ;
        }

        // 校验商品是否存在库存
        List<DetailDto> dtoList = detailDtoList.stream().filter(detailDto -> {
            Long skuId = detailDto.getSkuId();
            Integer skuNum = detailDto.getSkuNum();
            String hasStock = wareFeignClient.hasStock(skuId, skuNum);
            return "0".equals(hasStock);
        }).collect(Collectors.toList());
        if(dtoList.size() > 0) {
            throw new GmallException(ResultCodeEnum.SKU_STOCK_ERROR) ;
        }

        // 把订单的相关数据保存到对应数据库表中
        //  保存订单数据
        OrderInfo orderInfo = saveOrderInfo(tradeNo , orderSubmitDto);
        // 保存订单明细数据
        saveOrderDetail(orderInfo , orderSubmitDto);
        // 保存状态日志数据
        saveOrderStatusLog(orderInfo);
        // 远程调用service-cart微服务接口，删除选中的购物车数据
        cartFeignClient.deleteAllChecked();

        // 执行一个延迟任务

//        threadPool.schedule(() -> {
//            closeOrder(orderInfo.getId() , orderInfo.getUserId()) ;
//        } , 20 , TimeUnit.SECONDS) ;

        //准备消息
        Map<String , String> msg = new HashMap<>() ;
        msg.put("orderId" , String.valueOf(orderInfo.getId())) ;
        msg.put("userId" , String.valueOf(orderInfo.getUserId())) ;

        // 发送延迟消息
        rabbitTemplate.convertAndSend(RabbitConstant.ORDER_EXCHANGE , RabbitConstant.ORDER_ROUTING_KEY , JSON.toJSONString(msg));

        return String.valueOf(orderInfo.getId());
    }

    // 关闭订单操作
    public void closeOrder(Long orderId, Long userId) {
        // 根据订单id和用户id查询订单
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
        lambdaQueryWrapper.eq(OrderInfo::getId , orderId) ;
        lambdaQueryWrapper.eq(OrderInfo::getUserId , userId) ;
        OrderInfo orderInfo = orderInfoMapper.selectOne(lambdaQueryWrapper);

        /**
         * 在并发访问的时候会出现问题：判断已经结束，在执行修改订单状态为close的时候，用户进行了支付，那么此时订单的状态给修改为了已支付，然后在执行if中的代码，订单状态被改成CLOSE
         * 解决方案：
         * 1、加悲观锁
         * 2、乐观锁
         */
        // 判断订单的状态
        if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus()) && ProcessStatus.UNPAID.name().equals(orderInfo.getProcessStatus())) {

            // update order_info set order_status = "closed" , process_status = "close" where id = ? and order_status = "UNPAID" and process_status = "UNPAID"
            // 更新订单的状态为CLOSE
            orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
            lambdaQueryWrapper.eq(OrderInfo::getOrderStatus , OrderStatus.UNPAID.name()) ;
            lambdaQueryWrapper.eq(OrderInfo::getProcessStatus , ProcessStatus.UNPAID.name()) ;
            orderInfoMapper.update(orderInfo , lambdaQueryWrapper) ;

        }
    }

    @Override
    public void updateOrderStatusPayed(Map<String, String> params) {

        //保存支付信息payment_info表中
        PaymentInfo paymentInfo = buildPaymentInfo(params);
        paymentInfoMapper.insert(paymentInfo) ;

        //保存订单状态日志数据
        saveOrderStatusLogPayed(paymentInfo);

        // 修改订单支付状态
        String paymentStatus = paymentInfo.getPaymentStatus();
        if("TRADE_SUCCESS".equals(paymentStatus)) {
            OrderInfo orderInfo = updateOrderStatusAfterPayed(paymentInfo);
            // 发送扣减库存的消息到exchange.direct.ware.stock交换机上，携带的routingKey：ware.stock
            WareStockMsg wareStockMsg = buildWareStockMsg(orderInfo) ;
            rabbitTemplate.convertAndSend(RabbitConstant.WARE_STOCK_EXCHANGE , RabbitConstant.WARE_STOCK_ROUTING_KEY , JSON.toJSONString(wareStockMsg));
        }

    }

    @Override
    public void wareStockUpateStatus(String wareStockJSON) {
        WareStockResultMsg wareStockResultMsg = JSON.parseObject(wareStockJSON, WareStockResultMsg.class);
        Long orderId = wareStockResultMsg.getOrderId();

        // 查询数据库
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        // 判断订单的状态是否为已支付, 如果是已支付，那么此时就把订单的状态改成
        if(OrderStatus.PAID.name().equals(orderInfo.getOrderStatus()) && ProcessStatus.PAID.name().equals(orderInfo.getProcessStatus())) {

            // 修改订单的状态
            OrderStatus orderStatus = null ;
            ProcessStatus processStatus  = null ;
            String status = wareStockResultMsg.getStatus();
            switch (status) {
                case "DEDUCTED":        // 已减库存
                    orderStatus = OrderStatus.WAITING_DELEVER ;
                    processStatus = ProcessStatus.WAITING_DELEVER ;
                    break;
                case "OUT_OF_STOCK":        // 库存超卖
                    orderStatus = OrderStatus.WAITING_SCHEDULE ;
                    processStatus = ProcessStatus.STOCK_EXCEPTION ;
                    break;
            }

            orderInfo.setOrderStatus(orderStatus.name());
            orderInfo.setProcessStatus(processStatus.name());

            // 通过乐观锁进行修改
            LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
            lambdaQueryWrapper.eq(OrderInfo::getId , orderInfo.getId()) ;
            lambdaQueryWrapper.eq(OrderInfo::getUserId , orderInfo.getUserId()) ;
            lambdaQueryWrapper.eq(OrderInfo::getOrderStatus , OrderStatus.PAID.name()) ;
            lambdaQueryWrapper.eq(OrderInfo::getProcessStatus , ProcessStatus.PAID.name()) ;

            orderInfoMapper.update(orderInfo , lambdaQueryWrapper) ;

        }
    }

    @Override
    public List<WareStockMsg> orderSplit(Long orderId, String wareSkuMap) {
        // 查询订单数据
        OrderInfo oldOrderInfo = orderInfoMapper.selectById(orderId);

        // wareSkuMap: [{"wareId": "1", "skuIds": ["46","49"]},{"wareId": "2","skuIds": ["50"]}]
        List<WareSkuMapVo> wareSkuMapVoList = JSON.parseArray(wareSkuMap, WareSkuMapVo.class);
        List<WareStockMsg> wareStockMsgList = new ArrayList<>( );
        for(WareSkuMapVo wareSkuMapVo : wareSkuMapVoList) {

            // 创建新的订单
            OrderInfo orderInfo = new OrderInfo() ;
            orderInfo.setConsignee(oldOrderInfo.getConsignee());
            orderInfo.setConsigneeTel(oldOrderInfo.getConsigneeTel());

            // 查询订单明细
            LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId , oldOrderInfo.getId()) ;
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getUserId , oldOrderInfo.getUserId()) ;
            orderDetailLambdaQueryWrapper.in(OrderDetail::getSkuId , wareSkuMapVo.getSkuIds()) ;
            List<OrderDetail> orderDetails = orderDetailService.list(orderDetailLambdaQueryWrapper);
            BigDecimal totalAmount = orderDetails.stream().map(orderDetail -> new BigDecimal(orderDetail.getOrderPrice()).multiply(new BigDecimal(orderDetail.getSkuNum())))
                    .reduce((o1, o2) -> o1.add(o2)).get();
            orderInfo.setTotalAmount(totalAmount);

            orderInfo.setOrderStatus(oldOrderInfo.getOrderStatus());
            orderInfo.setUserId(oldOrderInfo.getUserId());
            orderInfo.setPaymentWay(oldOrderInfo.getPaymentWay());
            orderInfo.setDeliveryAddress(oldOrderInfo.getDeliveryAddress());
            orderInfo.setOrderComment(oldOrderInfo.getOrderComment());
            orderInfo.setOutTradeNo(oldOrderInfo.getOutTradeNo());
            orderInfo.setTradeBody(orderDetails.get(0).getSkuName());
            orderInfo.setCreateTime(new Date());
            orderInfo.setExpireTime(oldOrderInfo.getExpireTime());
            orderInfo.setProcessStatus(oldOrderInfo.getProcessStatus());

            orderInfo.setTrackingNo("");
            orderInfo.setParentOrderId(oldOrderInfo.getId());
            orderInfo.setImgUrl(orderDetails.get(0).getImgUrl());
            orderInfo.setProvinceId(0L);
            orderInfo.setOperateTime(new Date());
            orderInfo.setActivityReduceAmount(new BigDecimal("0"));
            orderInfo.setCouponAmount(new BigDecimal("0"));
            orderInfo.setOriginalTotalAmount(totalAmount);
            orderInfo.setFeightFee(new BigDecimal("0"));
            orderInfo.setRefundableTime(new Date());

            // 保存新订单数据
            orderInfoMapper.insert(orderInfo) ;

            // 创建新订单明细，保存
            List<OrderDetail> detailList = orderDetails.stream().map(oldOrderDetail -> {
                OrderDetail orderDetail = new OrderDetail();
                BeanUtils.copyProperties(oldOrderDetail, orderDetail);
                orderDetail.setId(null);
                orderDetail.setOrderId(orderInfo.getId());
                return orderDetail;
            }).collect(Collectors.toList());
            orderDetailService.saveBatch(detailList) ;


            // 构建拆单以后的结果数据
            WareStockMsg wareStockMsg = new WareStockMsg() ;
            wareStockMsg.setOrderId(orderInfo.getId());
            wareStockMsg.setConsignee(orderInfo.getConsignee());
            wareStockMsg.setConsigneeTel(orderInfo.getConsigneeTel());
            wareStockMsg.setOrderComment(orderInfo.getOrderComment());
            wareStockMsg.setOrderBody(orderInfo.getTradeBody());
            wareStockMsg.setDeliveryAddress(orderInfo.getDeliveryAddress());
            wareStockMsg.setPaymentWay("2");
            wareStockMsg.setWareId(wareSkuMapVo.getWareId());
            List<Sku> skuList = detailList.stream().map(orderDetail -> {
                Sku sku = new Sku();
                sku.setSkuId(orderDetail.getSkuId());
                sku.setSkuNum(Integer.parseInt(orderDetail.getSkuNum()));
                sku.setSkuName(orderDetail.getSkuName());
                return sku;
            }).collect(Collectors.toList());
            wareStockMsg.setDetails(skuList);
            wareStockMsgList.add(wareStockMsg) ;

        }

        // 更改老订单的状态为已拆单
        if(OrderStatus.PAID.name().equals(oldOrderInfo.getOrderStatus()) && ProcessStatus.PAID.name().equals(oldOrderInfo.getProcessStatus())) {

            oldOrderInfo.setOrderStatus(OrderStatus.SPLIT.name());
            oldOrderInfo.setProcessStatus(ProcessStatus.SPLIT.name());

            // 使用乐观锁进行修改
            LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
            lambdaQueryWrapper.eq(OrderInfo::getId , oldOrderInfo.getId()) ;
            lambdaQueryWrapper.eq(OrderInfo::getUserId , oldOrderInfo.getUserId()) ;
            lambdaQueryWrapper.eq(OrderInfo::getOrderStatus , OrderStatus.PAID.name()) ;
            lambdaQueryWrapper.eq(OrderInfo::getProcessStatus , ProcessStatus.PAID.name()) ;

            orderInfoMapper.update(oldOrderInfo , lambdaQueryWrapper) ;
        }

        return wareStockMsgList;
    }

    @Override
    public Page<OrderInfo> findOrderByPage(Integer pageNo, Integer pageSize) {

        Page<OrderInfo> page = new Page(pageNo , pageSize) ;
        String userId = AuthUserInfoUtils.getAuthUserInfo().getUserId();
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>() ;
        lambdaQueryWrapper.eq(OrderInfo::getUserId , Long.parseLong(userId)) ;
        lambdaQueryWrapper.ne(OrderInfo::getOrderStatus , OrderStatus.SPLIT.name()) ;
        lambdaQueryWrapper.ne(OrderInfo::getProcessStatus , ProcessStatus.SPLIT.name()) ;
        this.page(page, lambdaQueryWrapper);

        page.getRecords().stream().forEach(orderInfo -> {

            // 查询订单所对应的明细数据
            LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>() ;
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId , orderInfo.getId()) ;
            orderDetailLambdaQueryWrapper.eq(OrderDetail::getUserId , orderInfo.getUserId()) ;
            List<OrderDetail> orderDetailList = orderDetailService.list(orderDetailLambdaQueryWrapper);
            orderInfo.setOrderDetailList(orderDetailList);

        });

        return page;
    }

    private WareStockMsg buildWareStockMsg(OrderInfo orderInfo) {
        WareStockMsg wareStockMsg = new WareStockMsg();
        wareStockMsg.setOrderId(orderInfo.getId());
        wareStockMsg.setConsignee(orderInfo.getConsignee());
        wareStockMsg.setConsigneeTel(orderInfo.getConsigneeTel());
        wareStockMsg.setOrderComment(orderInfo.getOrderComment());
        wareStockMsg.setOrderBody(orderInfo.getTradeBody());
        wareStockMsg.setDeliveryAddress(orderInfo.getDeliveryAddress());
        wareStockMsg.setPaymentWay("2");

        // 根据订单的id和用户的id查询订单的明细
        LambdaQueryWrapper<OrderDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OrderDetail::getOrderId , orderInfo.getId()) ;
        lambdaQueryWrapper.eq(OrderDetail::getUserId , orderInfo.getUserId()) ;
        List<OrderDetail> orderDetailList = orderDetailService.list(lambdaQueryWrapper);
        List<Sku> skuList = orderDetailList.stream().map(orderDetail -> {
            Sku sku = new Sku();
            sku.setSkuId(orderDetail.getSkuId());
            sku.setSkuNum(Integer.parseInt(orderDetail.getSkuNum()));
            sku.setSkuName(orderDetail.getSkuName());
            return sku;
        }).collect(Collectors.toList());
        wareStockMsg.setDetails(skuList);

        return wareStockMsg;
    }

    private OrderInfo updateOrderStatusAfterPayed(PaymentInfo paymentInfo) {
        // 根据订单的id以及用户的id查询订单
        LambdaQueryWrapper<OrderInfo> orderInfoLambdaQueryWrapper = new LambdaQueryWrapper<>() ;
        orderInfoLambdaQueryWrapper.eq(OrderInfo::getId , Long.parseLong(paymentInfo.getOrderId())) ;
        orderInfoLambdaQueryWrapper.eq(OrderInfo::getUserId , paymentInfo.getUserId()) ;
        OrderInfo orderInfo = orderInfoMapper.selectOne(orderInfoLambdaQueryWrapper);

        // 判断订单的状态是否为未支付，已关闭，如果是那么此时把订单的状态改成已支付
        if((OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus()) || OrderStatus.CLOSED.name().equals(orderInfo.getOrderStatus()))
                && (ProcessStatus.UNPAID.name().equals(orderInfo.getProcessStatus()) ||  ProcessStatus.CLOSED.name().equals(orderInfo.getProcessStatus()) ) ) {

            // 更新订单的状态为已支付
            orderInfo.setOrderStatus(OrderStatus.PAID.name());
            orderInfo.setProcessStatus(ProcessStatus.PAID.name());
            orderInfoLambdaQueryWrapper.in(OrderInfo::getOrderStatus , OrderStatus.UNPAID.name() ,OrderStatus.CLOSED.name()) ;
            orderInfoLambdaQueryWrapper.in(OrderInfo::getOrderStatus , ProcessStatus.UNPAID.name() , ProcessStatus.CLOSED.name()) ;
            orderInfoMapper.update(orderInfo , orderInfoLambdaQueryWrapper) ;

        }

        return orderInfo ;
    }

    private void saveOrderStatusLogPayed(PaymentInfo paymentInfo) {
        String paymentStatus = paymentInfo.getPaymentStatus();
        OrderStatusLog orderStatusLog = OrderStatusLog.builder().orderId(Long.parseLong(paymentInfo.getOrderId()))
                .userId(paymentInfo.getUserId())
                .operateTime(new Date())
                .orderStatus("TRADE_SUCCESS".equals(paymentStatus) ? OrderStatus.PAID.name() : OrderStatus.UNPAID.name())
                .build();
        orderStatusLogMapper.insert(orderStatusLog);
    }

    // 构建PaymentInfo对象
    private PaymentInfo buildPaymentInfo(Map<String, String> params) {
        PaymentInfo paymentInfo = new PaymentInfo();

        String outTradeNo = params.get("out_trade_no");
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OrderInfo::getOutTradeNo , outTradeNo);
        OrderInfo orderInfo = orderInfoMapper.selectOne(lambdaQueryWrapper);

        paymentInfo.setUserId(orderInfo.getUserId());
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(String.valueOf(orderInfo.getId()));
        paymentInfo.setPaymentType("ALIPAY");

        String tradeNo= params.get("trade_no");
        paymentInfo.setTradeNo(tradeNo);
        paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
        paymentInfo.setSubject(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(params.get("trade_status"));
        paymentInfo.setCreateTime(new Date());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(JSON.toJSONString(params));

        return paymentInfo;
    }

    private void saveOrderStatusLog(OrderInfo orderInfo) {
        OrderStatusLog orderStatusLog = OrderStatusLog.builder()
                .userId(orderInfo.getUserId())
                .orderId(orderInfo.getId())
                .orderStatus(orderInfo.getOrderStatus())
                .operateTime(new Date())
                .build() ;
        orderStatusLogMapper.insert(orderStatusLog) ;
    }

    private void saveOrderDetail(OrderInfo orderInfo, OrderSubmitDto orderSubmitDto) {
        List<DetailDto> orderDetailList = orderSubmitDto.getOrderDetailList();
        List<OrderDetail> detailList = orderDetailList.stream().map(detailDto -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setUserId(orderInfo.getUserId());
            orderDetail.setOrderId(orderInfo.getId());
            orderDetail.setSkuId(detailDto.getSkuId());
            orderDetail.setSkuName(detailDto.getSkuName());
            orderDetail.setImgUrl(detailDto.getImgUrl());
            orderDetail.setOrderPrice(detailDto.getOrderPrice().intValue());
            orderDetail.setSkuNum(String.valueOf(detailDto.getSkuNum()));
            orderDetail.setCreateTime(new Date());
            orderDetail.setSplitTotalAmount(detailDto.getOrderPrice().multiply(new BigDecimal(detailDto.getSkuNum())));
            orderDetail.setSplitActivityAmount(new BigDecimal("0"));
            orderDetail.setSplitCouponAmount(new BigDecimal("0"));
            return orderDetail;
        }).collect(Collectors.toList());
        orderDetailService.saveBatch(detailList) ;
    }

    // 保存订单数据
    private OrderInfo saveOrderInfo(String tradeNo, OrderSubmitDto orderSubmitDto) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setConsignee(orderSubmitDto.getConsignee());
        orderInfo.setConsigneeTel(orderSubmitDto.getConsigneeTel());

        List<DetailDto> detailDtoList = orderSubmitDto.getOrderDetailList();
        BigDecimal totalAmount = detailDtoList.stream().map(detailDto -> detailDto.getOrderPrice().multiply(new BigDecimal(detailDto.getSkuNum())))
                .reduce((o1, o2) -> o1.add(o2)).get();
        orderInfo.setTotalAmount(totalAmount);

        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        String userId = AuthUserInfoUtils.getAuthUserInfo().getUserId();
        orderInfo.setUserId(Long.parseLong(userId));

        orderInfo.setPaymentWay("ONLINE");
        orderInfo.setDeliveryAddress(orderSubmitDto.getDeliveryAddress());
        orderInfo.setOrderComment(orderSubmitDto.getOrderComment());
        orderInfo.setOutTradeNo(tradeNo);

        DetailDto detailDto = detailDtoList.get(0);
        orderInfo.setTradeBody(detailDto.getSkuName());
        orderInfo.setCreateTime(new Date());
        Long expireTime = System.currentTimeMillis() + 1000 * 60 * 30 ;
        orderInfo.setExpireTime(new Date(expireTime));
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        orderInfo.setImgUrl(detailDto.getImgUrl());
        orderInfo.setOperateTime(new Date());
        orderInfo.setActivityReduceAmount(new BigDecimal("0"));
        orderInfo.setCouponAmount(new BigDecimal("0"));
        orderInfo.setOriginalTotalAmount(totalAmount);
        orderInfo.setFeightFee(new BigDecimal("0"));
        orderInfo.setRefundableTime(new Date());

        orderInfoMapper.insert(orderInfo) ;

        return orderInfo ;

    }
}
































